﻿
#region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;

#endregion

namespace MarketPulse.BusinessLogic.Common.StateMachine
{
    [Serializable]
    internal class EnquiryStateContext : IEnquiryStateContext
    {
        /// <summary>Property that stores the name of the class.</summary>
        private static readonly Type mClass = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;

        private IEnquiryState mState;

        private Enquiry mEnquiry;

        protected bool mThrowIfInvalid;

        internal EnquiryStateContext(Guid initialEnquiryStateGUID, Enquiry enquiry, bool throwIfInvalid)
        {
            mState = EnquiryStateFactory.Create(initialEnquiryStateGUID, throwIfInvalid);
            mEnquiry = enquiry;
            mThrowIfInvalid = throwIfInvalid;
        }

        public void SetState(IEnquiryState visitState)
        {
            mState = visitState;
            //mEnquiry.EnquiryStatusTypeGUID = mState.StateGuid;
        }

        public IEnquiryState GetState()
        {
            return mState;
        }

        public bool CanTransition(string eventName)
        {
            MethodInfo methodInfo = mClass.GetMethod(eventName);
            
            if (methodInfo == null)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("Unknown event: [ ");
                sb.Append(eventName);
                sb.Append(" ] !");
                throw new ArgumentException(sb.ToString());
            }

            ParameterInfo[] paramInfo = methodInfo.GetParameters();
            object[] args = new object[paramInfo.Length];
            args[0] = true;
            for (ushort i = 1; i < paramInfo.Length; ++i)
            {
                args[i] = null;
            }

            return (bool)mClass.InvokeMember(eventName, 
                                                BindingFlags.Public
                                                | BindingFlags.InvokeMethod
                                                | BindingFlags.IgnoreCase
                                                | BindingFlags.Instance, 
                                                null, this, args);
        }

        public bool Accept(bool tryTransition)
        {
            return mState.Accept(this, tryTransition);
        }


    }
}
